function emoticons(text){
    // The base URL of all our smilies
    var url = "images/smilies/";

    // A regex alternation that looks for all of them (be careful to use escapes
    // where necessary)
    var searchFor = /:D|:-D|:\)|:-\)|;\)|';-\)|:\(|:-\(|:o|:\?|8-\)|:x|:P/gi;

    // A map mapping each smiley to its image
    var map = {
        ":D"  : 'icon_e_biggrin.gif', // Capped version of the next
        ":d"  : 'icon_e_biggrin.gif', // Lower case version of the previous
        ":-D" : 'icon_e_biggrin.gif', // Capped version of the next
        ":-d" : 'icon_e_biggrin.gif', // Lower case version of the previous
        ":)"  : 'icon_e_smile.gif',
        ":-)" : 'icon_e_smile.gif',
        ";)"  : 'icon_e_wink.gif',
        "';-)" : 'icon_e_wink.gif',

        ":("  : 'icon_e_sad.gif',
        ":-(" : 'icon_e_sad.gif',
        ":O"  : 'icon_e_surprised.gif', // Capped version of the next
        ":o"  : 'icon_e_surprised.gif', // Lower case version of the previous
        ":?"  : 'icon_e_confused.gif',
        "8-)" : 'icon_cool.gif',

        ":X"  : 'icon_mad.gif',    // Capped version of the next
        ":x"  : 'icon_mad.gif',    // Lower case version of the previous
        ":P"  : 'icon_razz.gif',   // Capped version of the next
        ":p"  : 'icon_razz.gif'    // Lower case version of the previous
    };

    // Do the replacements
    text = text.replace(searchFor, function(match) {
        var rep;

        // Look up this match to see if we have an image for it
        rep = map[match];

        // If we do, return an `img` tag using that smiley icon; if not, there's
        // a mis-match between our `searchFor` regex and our map of
        // smilies, but handle it gracefully by returning the match unchanged.
        return rep ? '<img src="' + url + rep + '" class="emoticons" />' : match;
    });

    return (text);
}